package com.hitqz.robot.camera.netty;

import com.hitqz.robot.camera.util.PelcodCacheUtil;
import com.hitqz.robot.camera.util.PelcodCameraToolkit;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;

@Slf4j
public class PelcodMessageHandler extends ChannelInboundHandlerAdapter {


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        // 处理接收到的消息，这里假设 msg 是你解码后的对象
        if (msg instanceof PelcodMessage message) {
            // 在这里处理消息，比如解析内容、处理业务逻辑等
            handleMessage(ctx, message);
        } else {
            log.warn("[pelcod]channel read unknown message type: {}", msg.getClass().getName());
        }
    }

    // 处理消息的业务逻辑
    private void handleMessage(ChannelHandlerContext ctx, PelcodMessage message) {
        // 根据命令进行分发
        NetworkServiceThreadPool.dealMessage(() -> {
            this.simpleHandle(ctx, message);
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 处理异常
        log.error("[pelcod]channel exception caught in TrackMessageHandler", cause);
        ctx.close();  // 关闭连接
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 当连接建立时的处理逻辑
        log.info("[pelcod]channel connection active: {}", ctx.channel().remoteAddress());
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // 当连接关闭时的处理逻辑
        log.info("[pelcod]channel connection inactive: {}", ctx.channel().remoteAddress());
        super.channelInactive(ctx);
    }


    /**
     * 简单处理一些没有子命令的消息
     *
     * @param ctx
     * @param message
     */
    private void simpleHandle(ChannelHandlerContext ctx, PelcodMessage message) {
        // 获取消息中的数据
        byte[] cmds = message.getCmd();
        byte[] data = message.getData();
        ByteBuf buffer = ctx.alloc().buffer(data.length);
        buffer.writeBytes(data);
        try {
            // 读取命令字节
            int cmd = cmds[1]&0xFF;// 转换成无符号
            switch (cmd) {
                case 0x59: {
                    Float pan = BigDecimal.valueOf(buffer.readShort() & 0xFFFF).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).floatValue();
                    PelcodCacheUtil.put(PelcodCacheUtil.KEY_PAN_VALUE, pan);
                    PelcodCameraToolkit.release(PelcodCacheUtil.KEY_PAN_VALUE,true);
                    log.info("[pelcod]current pan:{}",pan);
                    break;
                }
                case 0x5B: {
                    // 16位的无符号整数  9000~27000
                    int tiltRaw = buffer.readShort() & 0xFFFF;;
                    log.info("[pelcod]current tilt raw data:{}",tiltRaw);
                    if (tiltRaw>18000){
                        tiltRaw =(short) (36000 - tiltRaw);
                    }else {
                        tiltRaw =(short) (-1 * tiltRaw);
                    }
                    Float tilt = BigDecimal.valueOf(tiltRaw).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).floatValue();
                    log.info("[pelcod]current tilt convert:{}",tilt);
                    PelcodCacheUtil.put(PelcodCacheUtil.KEY_TILT_VALUE, tilt);
                    PelcodCameraToolkit.release(PelcodCacheUtil.KEY_TILT_VALUE,true);
                    break;
                }
                default:
                    log.warn("[pelcod] unknown main cmd: {},strategy no found!", String.format("%02X", cmd));
                    break;
            }

        } catch (Exception e) {
            log.warn("[pelcod]simpleHandle error", e);
        } finally {
            // 确保 ByteBuf 在使用完后释放，防止内存泄漏
            buffer.release();
        }

    }


}
